using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;


namespace WPF_Media_Player
{
    /// <summary>
    /// prvoides a media player with a track list and volume controls and rating system
    /// </summary>
    public partial class ucMediaPlayer : System.Windows.Controls.UserControl
    {
        #region Instance Fields
        private double mediaItemsWidth = -1;
        bool singleMode = false;
        private Dictionary<string, MediaItem> mediaItems = new Dictionary<string, MediaItem>();
        ToggleButton[] btnStars = new ToggleButton[5];
        #endregion
        #region Ctor
        public ucMediaPlayer()
        {
            InitializeComponent();

            sliderTime.IsEnabled = false;
            sliderVolume.IsEnabled = false;
            txtRating.Visibility = Visibility.Hidden;
        }
        #endregion
        #region Private methods
               
        /// <summary>
        /// set the rating to the current stars for the current media items
        /// </summary>
        private void btnStars_Click(object sender, RoutedEventArgs e)
        {
            int rating = 0;
            for (int i = 0; i < 5; i++)
            {
                rating += btnStars[i].IsChecked.Value ? 1 : 0;
            }
            string key = mediaPlayerMain.Source.AbsolutePath.Substring(mediaPlayerMain.Source.AbsolutePath.LastIndexOf(@"/")+1);
            mediaItems[key].ItemRating = rating;
        }

        /// <summary>
        /// Stop media when ended
        /// </summary>
        private void mediaPlayerMain_MediaEnded(object sender, RoutedEventArgs e)
        {
            mediaPlayerMain.Stop();
        }

        /// <summary>
        /// Initialise UI elements based on current media item
        /// </summary>
        private void mediaPlayerMain_MediaOpened(object sender, RoutedEventArgs e)
        {
            sliderTime.Maximum = mediaPlayerMain.NaturalDuration.TimeSpan.TotalMilliseconds;
            sliderTime.IsEnabled = mediaPlayerMain.IsLoaded;
            sliderVolume.IsEnabled = mediaPlayerMain.IsLoaded;
        }

        /// <summary>
        /// stop the media playing
        /// </summary>
        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            // The Stop method stops and resets the media to be played from
            // the beginning.
            mediaPlayerMain.Stop();
        }

        /// <summary>
        /// pause the media playing
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPause_Click(object sender, RoutedEventArgs e)
        {
            // The Pause method pauses the media if it is currently running.
            // The Play method can be used to resume.
            mediaPlayerMain.Pause();
        }

        /// <summary>
        /// play the media
        /// </summary>
        private void btnPlay_Click(object sender, RoutedEventArgs e)
        {
             
            mediaPlayerMain.Source = null;
            mediaPlayerMain.Source = new Uri(@"http://www.informatik.uni-freiburg.de/~kiro/videos/KiRoPaderborn2.mpeg");//mel.Source;
            mediaPlayerBorder.Visibility = Visibility.Visible;
            mediaPlayerMain.Play();
            mediaPlayerMain.Volume = (double)sliderVolume.Value;
                        
            //mediaPlayerMain.Play();
            //mediaPlayerMain.Volume = (double)sliderVolume.Value;
        }

        /// <summary>
        /// collapse/expand media items to take up entire grid row (so no media item list)
        /// </summary>
        private void btnMediaPlayerMain_Click(object sender, RoutedEventArgs e)
        {
            if (mediaPlayerBorder != null)
            {
                int col = Grid.GetColumn(mediaPlayerBorder);
                //work out which columns need to be resized in grid
                for (int indexCol = 0; indexCol < grdMain.ColumnDefinitions.Count; indexCol++)
                {
                    if (indexCol != col)
                    {
                        //grid column for media length animations
                        GridLengthAnimation gla = new GridLengthAnimation();
                        gla.From = new GridLength(singleMode ? 10 : mediaItemsWidth, GridUnitType.Pixel);
                        gla.To = new GridLength(singleMode ? mediaItemsWidth : 10, GridUnitType.Pixel);
                        gla.Duration = new TimeSpan(0, 0, 2);
                        grdMain.ColumnDefinitions[indexCol].BeginAnimation(ColumnDefinition.WidthProperty, gla);
                        //opacity (fade media items list)
                        DoubleAnimation hideShowOpacAnim = new DoubleAnimation();
                        hideShowOpacAnim.From = singleMode ? 0.0 : 1.0;
                        hideShowOpacAnim.To = singleMode ? 1.0 : 0.0;
                        hideShowOpacAnim.Duration = new Duration(TimeSpan.Parse("0:0:1"));
                    }
                }
            }
            singleMode = !singleMode;            
        }

        /// <summary>
        /// seek media to position (x)
        /// </summary>
        private void SeekToMediaPosition(object sender, RoutedPropertyChangedEventArgs<double> args)
        {
            int SliderValue = (int)sliderTime.Value;
            // Overloaded constructor takes the arguments days, hours, minutes, seconds, miniseconds.
            // Create a TimeSpan with miliseconds equal to the slider value.
            TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);
            mediaPlayerMain.Position = ts;
        }

        /// <summary>
        /// change media volume to position (x)
        /// </summary>
        private void ChangeMediaVolume(object sender, RoutedPropertyChangedEventArgs<double> args)
        {
            mediaPlayerMain.Volume = (double)sliderVolume.Value;
        }

        /// <summary>
        /// create star buttons
        /// </summary>
        private void createStarButtons()
        {
            string key = mediaPlayerMain.Source.AbsolutePath.Substring(mediaPlayerMain.Source.AbsolutePath.LastIndexOf(@"/") + 1);
            int itemRating = 1;//mediaItems[key].ItemRating;

            starStack.Children.Clear();

            for (int i = 0; i < 5; i++)
            {
                btnStars[i] = new ToggleButton();
                btnStars[i].Width = 14;
                btnStars[i].Height = 20;
                btnStars[i].IsChecked = itemRating >= i+1;
                btnStars[i].Click += new RoutedEventHandler(btnStars_Click);
                btnStars[i].Checked += new RoutedEventHandler(btnStars_Checked);
                btnStars[i].Unchecked += new RoutedEventHandler(btnStars_Unchecked);
                btnStars[i].IsEnabled = false;
                addStarStyle(btnStars[i]);
            }
            btnStars[0].IsEnabled = true;
//
//            //show the text only if the buttons were added successfully
            txtRating.Visibility = starStack.Children.Count > 0 ? Visibility.Visible : Visibility.Hidden;
        }

        /// <summary>
        /// work out which other stars can be checked
        /// </summary>
        private void btnStars_Checked(object sender, RoutedEventArgs e)
        {

            ToggleButton starButton = (ToggleButton)sender;
            int pos = -1;

            for (int i = 0; i < 5; i++)
            {
                if (btnStars[i].Equals(starButton))
                {
                    pos = i;
                }
            }

            //special case need to reset position 0 star, as it will still be enabled
            //from when the stars were created
            if (pos == 1)
                btnStars[0].IsEnabled = false;

            //only allow next consecutive starButton to be toggled
            //basically must be checked in order
            if (pos > -1 && pos < 4)
            {
                btnStars[pos].IsEnabled = false;
                btnStars[pos + 1].IsEnabled = true;
            }
        }

        /// <summary>
        /// work out which other stars can be Unchecked
        /// </summary>
        private void btnStars_Unchecked(object sender, RoutedEventArgs e)
        {
            ToggleButton starButton = (ToggleButton)sender;
            int pos = -1;

            for (int i = 0; i < 5; i++)
            {
                if (btnStars[i].Equals(starButton))
                {
                    pos = i;
                }
            }
            //only allow next consecutive starButton to be toggled
            //basically must be checked in order
            if (pos > 0 && pos < 5)
            {
                if( pos < 4)
                    btnStars[pos+1].IsEnabled = false;
                btnStars[pos].IsEnabled = true;
                btnStars[pos - 1].IsEnabled = true;
            }
        }

        /// <summary>
        /// add Style to star buttons
        /// </summary>
        private void addStarStyle(ToggleButton btnStar)
        {
            Style starStyle = this.Resources["StarToggleButton"] as Style; ;
            if (starStyle != null)
            {
                btnStar.Style = starStyle;
                starStack.Children.Add(btnStar);
            }
        }

        /// <summary>
        /// open new media item based on item clicked
        /// </summary>
        private void btnMediaItems_Clicked(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            MediaElement mel = b.Content as MediaElement;
            mediaPlayerMain.Source = null;
            mediaPlayerMain.Source = new Uri(@"http://www.informatik.uni-freiburg.de/~kiro/videos/KiRoPaderborn2.mpeg");//mel.Source;
            mediaPlayerBorder.Visibility = Visibility.Visible;
            mediaPlayerMain.Play();
            mediaPlayerMain.Volume = (double)sliderVolume.Value;
            createStarButtons();
        }

        
      
        #endregion 
    }
}